//
//  ViewController.m
//  UI20_XML SAXAndDOM
//
//  Created by dllo on 16/8/10.
//  Copyright © 2016年 yh. All rights reserved.
//

#import "ViewController.h"
#import "Student.h"
#import "GDataXMLNode.h"
#import "XMLReader.h"
@interface ViewController () <NSXMLParserDelegate>
@property (nonatomic, strong) NSMutableArray *stuArray;
@property (nonatomic, copy) NSString *currentElementName;

@property (nonatomic, strong) NSMutableArray *DOMStuArray;

@end

@implementation ViewController
// XML分为两种解析方式
// 1. 逐行解析 使用系统的解析器NSXMLParser
// 2.
// SOAP协议 数据


- (IBAction)SAX:(id)sender {
    NSString *path = [[NSBundle mainBundle] pathForResource:@"stu_xml" ofType:@".xml"];
    NSData *data = [NSData dataWithContentsOfFile:path];
    NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:data];
    xmlParser.delegate = self;
    // 运行
    [xmlParser parse];
}
// 解析开始 初始化数组
- (void)parserDidStartDocument:(NSXMLParser *)parser {
    self.stuArray = [NSMutableArray array];

}
// 逐行解析 遇到节点头
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName attributes:(NSDictionary<NSString *, NSString *> *)attributeDict {
//    NSLog(@"节点头%@", elementName);
    // 逐行运行 将每一行的节点名赋值给定义的变量(记录节点 方便后期赋值)
    _currentElementName = elementName;
    // 遇到节点student 创建model
    if ([elementName isEqualToString:@"student"]) {
        Student *stu = [[Student alloc] init];
        [_stuArray addObject:stu];
    }
}
// 节点的值 (根据节点决定值)
- (void)parser:(NSXMLParser *)parser foundCharacters:(nonnull NSString *)string {
    // string是"\n" "\t"
//    if (![string hasSuffix:@" "] && ![string hasSuffix:@"\n"]) {
//        NSLog(@"节点的值%@-------节点值结束", string);
    if (_currentElementName) {
        Student *stu = [_stuArray lastObject];
        // 赋值 (将节点名和节点值 通过 setValue forKey 赋值给model)
        [stu setValue:string forKey:_currentElementName];
    }
    //    }
}

// 逐行解析 遇到节点尾 (直到数据每行都运行完毕执行该方法)
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName {
//    NSLog(@"节点尾/%@", elementName);
        // 在节点尾 给节点名赋值为空
        _currentElementName = nil;
}

// 解析结束
- (void)parserDidEndDocument:(NSXMLParser *)parser {
    NSLog(@"%@", _stuArray);
}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
    NSLog(@"解析失败%@", parseError);
}

// 第二种解析方式 DOM(document Object model)解析 不是逐行解析
// 关于GDataXMLNode的引入
// 1. 引入.h .m 文件
// 2. 引入系统libxml2.tbd
// 3. 根据GDataXMLNode头文件 添加   /usr/include/libxml2
// 4. 如果是ARC环境需要对该文件进行mrc编译(添加 -fno-objc-arc)
- (IBAction)DOM:(id)sender {
    self.DOMStuArray = [NSMutableArray array];
    NSString *path = [[NSBundle mainBundle] pathForResource:@"stu_xml" ofType:@".xml"];
    NSData *data = [NSData dataWithContentsOfFile:path];
    NSError *error = nil;
    // 创建GDataXMLDocument对象
    // 根据xml的Data数据生成一个树形结构的 document
    GDataXMLDocument *document = [[GDataXMLDocument alloc] initWithData:data options:0 error:&error];
    // 根据document 获取根节点
    GDataXMLElement *rootElement = [document rootElement];
    // 根据根节点 获取子节点数组
    NSArray *rootChildrenElementArray = rootElement.children;
    NSLog(@"ARRAY %@", rootChildrenElementArray);

    // 遍历子节点数组 得到对应所有student节点
    for (GDataXMLElement *childElement in rootChildrenElementArray) {
        Student *stu = [Student new];
        [self.DOMStuArray addObject:stu];
        // 遍历所有student的所有子节点
        for (GDataXMLElement *grandSonElement in childElement.children) {
            // .stringValue(节点值) .name(节点名)
            [stu setValue:grandSonElement.stringValue forKey:grandSonElement.name];
        }
    }
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    // 利用XMLReader 将XML结构的数据转化为dictionary(json类型)
    NSString *path = [[NSBundle mainBundle] pathForResource:@"stu_xml" ofType:@".xml"];
    NSData *data = [NSData dataWithContentsOfFile:path];
    NSError *error = nil;
    NSDictionary *dic = [XMLReader dictionaryForXMLData:data error:&error];
    NSLog(@"%@", dic);
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
